/*
 * Wideget.c
 *      Author: zj
 */
#include "stdafx.h"
#include "sysarch.h"
#include "SWidget.h"
#include "SimLcd.h"
#include "sysapi.h"
#include "MenuIf.h"

extern void StateTask();
DWORD g_dwStateTaskClick = 0;
bool g_fLcdRefresh = true;
bool g_LocalUpgrade = false;

OS_SEM g_SemGUI;

void WIDGET_Lock(void)
{ /*
     if (WIDGET_mtxinit == 0)
     {
         pthread_mutex_init(&WIDGET_mtx, NULL);
         WIDGET_mtxinit = 1;
     }
     pthread_mutex_lock(&WIDGET_mtx);
   */
    OSSemPend(g_SemGUI);
}
void WIDGET_UnLock(void)
{
    //pthread_mutex_unlock(&WIDGET_mtx);
    OSSemPost(g_SemGUI);
}


struct AppKeyStruct GetKey(void)
{

    static char flag = 0;
    static int OldS;
    struct AppKeyStruct mkey;

    if (flag == 0)
    {
        flag = 1;
        OldS = time((time_t*)NULL);
    }

    mkey.key = GUI_GetKey();
    if (mkey.key != 0)
    {
        //BlightOn(true);
        OldS = time((time_t*)NULL);
        //g_iLcdStartClick = -100;
    }
/*
    if (mkey.key == (KEY_OK | KEY_ESC))
    { //����
        //TestPrj(NULL);
    }
    else if (mkey.key == (KEY_UP | KEY_DOWN))
    { //��
        TermUpdate(NULL);
    }
    else if (mkey.key == (KEY_LEFT | KEY_RIGHT))
    { //����ʱ��
        CommSetTmDateTime((void*)0x4);
    }
    else if (mkey.key == (KEY_LEFT | KEY_OK | KEY_ESC))
    {
        StopWdg(NULL);
    }
    else if (mkey.key == (KEY_LEFT | KEY_OK))
    {
        //DcAdj(NULL);
    }*/
    mkey.idle = time((time_t*)NULL) - OldS;

    return mkey;
}
int LCD_GetmaxCharPerLine(void)
{
    return LCD_SIM_WIDTH / FONT_WIDTH;
}
int LCD_GetmaxLinePerScreen(void)
{
    return LCD_SIM_HEIGHT / FONT_HEIGHT;
}
int LCD_GetFontWidth()
{
    return FONT_WIDTH;
}
int LCD_GetFontHeight()
{
    return FONT_HEIGHT;
}
void clear_screen_rec(int x0, int y0, int x1, int y1)
{
    WIDGET_Lock();
    for (int i = x0; i < x1; i++)
    {
        for (int n = y0; n < y1; n++)
        {
            set_pix(i, n, 0);
        }
    }
    WIDGET_UnLock();
}
void DrawGdFont16x16(const char text[], int x, int y)
{
    WIDGET_Lock();
    for (int i = 0; i < 32; i += 2)
    {
        for (int bit = 0; bit < 8; bit++)
        {
            set_pix(x + 7 - bit, y + i / 2, 1 & (text[i] >> bit)? GUI_WHITE : GUI_BLACK);
            set_pix(x + 8 + 7 - bit, y + i / 2, 1 & (text[i + 1] >> bit)? GUI_WHITE : GUI_BLACK);
        }
    }
    WIDGET_UnLock();
}
int GUI_DispStringAtLock(const char *s, int x, int y, GUI_COLOR fColor, GUI_COLOR bColor)
{
    int lineCnt = 0;

    WIDGET_Lock();

    GUI_SetBkColor(bColor);
    GUI_SetColor(fColor);
    GUI_DispStringAt(s, x, y);
    for (unsigned int i = 0; i < strlen(s); i++)
    {
        if (s[i] == '\n')
        {
            lineCnt++;
            GUI_DispStringHCenterAt(s + i + 1, 0, y + LCD_GetFontHeight() * lineCnt);
        }
    }

    WIDGET_UnLock();
    return lineCnt;
}
int GUI_DispStringHCenterAtLock(const char *s, int x, int y, GUI_COLOR fColor, GUI_COLOR bColor)
{
    int lineCnt = 0;

    WIDGET_Lock();

    GUI_SetBkColor(bColor);
    GUI_SetColor(fColor);
    GUI_DispStringHCenterAt(s, x, y);
    for (unsigned int i = 0; i < strlen(s); i++)
    {
        if (s[i] == '\n')
        {
            lineCnt++;
            GUI_DispStringHCenterAt(s + i + 1, x, y + LCD_GetFontHeight() * lineCnt);
        }
    }

    WIDGET_UnLock();
    return lineCnt;
}
void GUI_DrawRectLock(int x0, int y0, int x1, int y1)
{
    WIDGET_Lock();
    GUI_DrawRect(x0, y0, x1, y1);
    WIDGET_UnLock();
}

int MsgBox(char msg[], char retKey, int retTime)
{
    int time = 0;
    char buff[32];

    //char LcdDispBuff[LCD_SIM_HEIGHT * LCD_SIM_WIDTH / 8];
    //bak_lcd_disp(LcdDispBuff);

    int len = strlen(msg);
    int maxLinePerScreen = LCD_GetmaxLinePerScreen();
    int maxCharPerLine = LCD_GetmaxCharPerLine() - 2;
    int tatolLine = len / 2 / maxCharPerLine + 1;

    for (unsigned int i = 0; i < strlen(msg); i++)
    {
        if (msg[i] == '\n')
        {
            tatolLine++;
        }
    }

    if (tatolLine > 7)
    {
        tatolLine = 7;
    }

    int y = (maxLinePerScreen - tatolLine) / 2;
    if (y < 1)
    {
        y = 1;
    }
    if (y >= maxLinePerScreen)
    {
        y = maxLinePerScreen - 1;
    }

    clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());  
    GUI_DrawRectLock(4, y * LCD_GetFontHeight() - 4, 
                     LCD_GET_XSIZE() - 4, (y + tatolLine) * LCD_GetFontHeight());

    char *p = msg;
    int muxflag = 0;
    while (len > 0)
    {
        if (len >= 2 * maxCharPerLine)
        {
            int x1 = 0;
            int y1 = 0;
            unsigned char *ustr = (unsigned char*)p;
            int i = 0;
            for (i = 0; i < len; i++)
            {
                if (x1 > maxCharPerLine * 2) //����д���£����Զ�����
                {
                    x1 = 0;
                    y1++;
                    break;
                }
                else if (x1 > maxCharPerLine * 2 - 1 && ustr[i] >= 128)          //����д���º��֣����Զ�����
                {
                    x1 = 0;
                    y1 += 1;
                    break;
                }

                if (ustr[i] >= 128)          //���λΪ1
                {
                    i++;
                    x1 += 2;    //д��һ�����ֹ��������λ�����֣�
                }
                else if (*(ustr + i) < 32) //����ASC��С��32�Ĳ��õ��ַ��Զ���ȥ
                {

                }
                else    //��Ӣ���ַ�
                {
                    x1++;   //д��һ���ַ�������1λ
                }
            }

            muxflag = 1;
            memcpy(buff, p, i);
            p += i;
            buff[i] = 0;
            len -= i;
            GUI_DispStringHCenterAtLock(buff, LCD_GET_XSIZE() / 2, y * LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
        }
        else
        {
            memcpy(buff, p, len);
            buff[len] = 0;
            len = 0;
            if (muxflag == 1)
            {
                GUI_DispStringAtLock(buff, LCD_GetFontWidth(), y * LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
            }
            else
            {
                GUI_DispStringHCenterAtLock(buff, LCD_GET_XSIZE() / 2, y * LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
            }
        }

        y++;
        if (y > 7)
        {
            break;
        }
    }

    LcdRefresh();
    while (time <= retTime / 100)
    {
        Sleep(100);
        time++;
        BYTE key = GetKey().key;
        if (key == retKey)
        {
            return 0;
        }
        else if (key == KEY_OK)
        {
            return 1;
        }

        DWORD dwTick = GetTick();
        if (g_dwStateTaskClick == 0 || dwTick > (g_dwStateTaskClick + 500))
        {
            //StateTask();
            g_fLcdRefresh = true;
            g_dwStateTaskClick = dwTick;
        }

        if (g_fLcdRefresh)
        {
            g_fLcdRefresh = false;
            LcdRefresh();
        }
    }

    //res_lcd_disp(LcdDispBuff);
    return 0;
}

static char BinCharTable[] = { '0', '1', };
static char HexCharTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '.',
                               ':', ' ', };
static char DecCharTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ' ', '-', };
static char AscCharTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
                               'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '.', '#', ':',
                               '-', ' ', '@',
                               'a', 'b', 'c', 'd', 'e', 'f', 'g',
                               'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', };
static char PureDecCharTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', };
int EditBox(int y, char title[], char text[], int retTime, int txtSize, int dataType)
{
    struct AppKeyStruct mkey;
    char txtBuf[96];
    int txtPos = 0;
    int curPosInCharTable = 0;
    int charTableSize = 0;
    char *charTable;
    int haveTitle = 0;

    y = y * LCD_GetFontHeight();

    if (strlen(title) > 0)
    {
        haveTitle = 1;
    }

    memset(txtBuf, ' ', sizeof(txtBuf));
    if (txtSize == 0)
    {
        txtSize = sizeof(txtBuf);
    }
    else
    {
        txtSize += 2;
        if (txtSize > (int)sizeof(txtBuf))
        {
            txtSize = sizeof(txtBuf);
        }
    }

    text[txtSize - 2] = 0;
    int initTextSize = strlen(text);
    if (initTextSize > txtSize - 2)
    {
        initTextSize = txtSize - 2;
    }
    if (initTextSize > 0)
    {
        memcpy(txtBuf, text, initTextSize);
    }
    txtBuf[txtSize - 1] = 0;

    switch (dataType)
    {
    case DATA_HEX:
        charTable = HexCharTable;
        charTableSize = sizeof(HexCharTable);
        break;
    case DATA_DEC:
        charTable = DecCharTable;
        charTableSize = sizeof(DecCharTable);
        break;
	case DATA_PUREDEC:
		charTable = PureDecCharTable;
		charTableSize = sizeof(PureDecCharTable);
		break;
    case DATA_BIN:
        charTable = BinCharTable;
        charTableSize = sizeof(BinCharTable);
        break;
    default:
        charTable = AscCharTable;
        charTableSize = sizeof(AscCharTable);
        break;
    }

    int totalLine = txtSize / ((LCD_SIM_WIDTH - 8) / LCD_GetFontWidth()) / 2 + 2;
    int dispPosX = 0;
    int dispPosY = y;
    for (int i = 0; i < totalLine; i++)
    {
        GUI_DispStringAtLock("                            ", 0, y + LCD_GetFontHeight() * i, GUI_WHITE, GUI_BLACK);
    }
    while (1)
    {
        if (haveTitle == 1)
        {
            for (int i = 0; i <= totalLine; i++)
            {
                GUI_DrawRectLock(0, y - 1, LCD_SIM_WIDTH - 1, y + LCD_GetFontHeight() * i - 1);
            }
            GUI_DispStringHCenterAtLock(title, LCD_SIM_WIDTH / 2, y, GUI_WHITE, GUI_BLACK);
        }
        for (int i = 0; i < txtSize; i++)
        {
            char tmp[2] = { 0, 0, };
            tmp[0] = txtBuf[i];

            dispPosX = (4 + i * LCD_GetFontWidth() / 2) % (LCD_SIM_WIDTH - 7);
            dispPosY = y + i * LCD_GetFontWidth() / 2 / (LCD_SIM_WIDTH - 7) * LCD_GetFontHeight();

            if (i == txtPos)
            {
                GUI_DispStringAtLock(tmp, dispPosX, dispPosY + LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);
            }
            else
            {
                GUI_DispStringAtLock(tmp, dispPosX, dispPosY + LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
            }
        }

        for (int i = 0; i < charTableSize; i++)
        {
            if (txtBuf[txtPos] == charTable[i])
            {
                curPosInCharTable = i;
                break;
            }
        }

        LcdRefresh();

        while (1)
        {
            Sleep(100);
            mkey = GetKey();
            if (mkey.key != 0)
            {
                break;
            }

            if (mkey.idle > retTime / 1000 || mkey.key == KEY_ESC)
            {
                return -1;
            }

            DWORD dwTick = GetTick();
            if (g_dwStateTaskClick == 0 || dwTick > (g_dwStateTaskClick + 500))
            {
                //StateTask();
                g_fLcdRefresh = true;
                g_dwStateTaskClick = dwTick;
            }

            if (g_fLcdRefresh)
            {
                g_fLcdRefresh = false;
                LcdRefresh();
            }
        }

        if (mkey.key == KEY_ESC)
        {
            return -1;
        }
        if (mkey.key == KEY_OK)
        {
            if (txtSize > 2)
            {
                memcpy(text, txtBuf, txtSize - 2);
            }
            return txtPos;
        }
        if (mkey.key == KEY_UP)
        {
            curPosInCharTable++;
            if (curPosInCharTable >= charTableSize)
            {
                curPosInCharTable = 0;
            }
            txtBuf[txtPos] = charTable[curPosInCharTable];
        }
        if (mkey.key == KEY_DOWN)
        {
            curPosInCharTable--;
            if (curPosInCharTable < 0)
            {
                curPosInCharTable = charTableSize - 1;
            }
            txtBuf[txtPos] = charTable[curPosInCharTable];
        }
        if (mkey.key == KEY_LEFT)
        {
            if (txtPos > 0)
            {
                txtPos--;
            }
        }
        if (mkey.key == KEY_RIGHT)
        {
            if (txtPos < txtSize - 3)
            {
                txtPos++;
            }
        }

        for (int i = 0; i < charTableSize; i++)
        {
            if (txtBuf[txtPos] == charTable[i])
            {
                curPosInCharTable = i;
                break;
            }
        }
    }

    return -1;
}

//140228 wulh add begin
int EditDateBox(int y, char title1[], char title2[], char text[], int retTime, int txtSize, int dataType)
{
	struct AppKeyStruct mkey;
	char txtBuf[96];
	int txtPos = 0;
	int curPosInCharTable = 0;
	int charTableSize = 0;
	char *charTable;
	int haveTitle = 0;
	int haveTitle2 = 0;

	clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());

	y = y * LCD_GetFontHeight();

	if (strlen(title1) > 0)
	{
		haveTitle = 1;
	}

	if(strlen(title2) > 0)
	{
		haveTitle2 = 1;
	}
	

	memset(txtBuf, ' ', sizeof(txtBuf));
	if (txtSize == 0)
	{
		txtSize = sizeof(txtBuf);
	} else
	{
		txtSize += 2;
		if (txtSize > (int) sizeof(txtBuf))
		{
			txtSize = sizeof(txtBuf);
		}
	}

	text[txtSize - 2] = 0;
	int initTextSize = strlen(text);
	if (initTextSize > txtSize - 2)
	{
		initTextSize = txtSize - 2;
	}
	if (initTextSize > 0)
	{
		memcpy(txtBuf, text, initTextSize);
	}
	txtBuf[txtSize - 1] = 0;

	switch (dataType) 
	{
	case DATA_HEX:
		charTable = HexCharTable;
		charTableSize = sizeof(HexCharTable);
		break;
	case DATA_DEC:
		charTable = DecCharTable;
		charTableSize = sizeof(DecCharTable);
		break;
	case DATA_BIN:
		charTable = BinCharTable;
		charTableSize = sizeof(BinCharTable);
		break;	
	default:
		charTable = AscCharTable;
		charTableSize = sizeof(AscCharTable);
		break;
	}

	int totalLine = txtSize / ((LCD_SIM_WIDTH - 8) / LCD_GetFontWidth()) / 2 + 2;
	int dispPosX = 0;
	int dispPosY = y;
	for (int i = 0; i < totalLine; i++)
	{
		GUI_DispStringAtLock("                            ", 0, y + LCD_GetFontHeight() * i, GUI_WHITE, GUI_BLACK);
	}

	//��ѡ�й���ƶ����ַ����һ���ַ�
	txtPos = txtSize - 3;
	
	while (1)
	{
		if (haveTitle == 1)
		{
			GUI_DispStringHCenterAtLock(title1, LCD_SIM_WIDTH / 2, LCD_GetFontHeight() + 2, GUI_WHITE, GUI_BLACK);
		}

		if(haveTitle2 == 1)
		{
			GUI_DispStringAtLock(title2, LCD_SIM_WIDTH / 20 , 3 * LCD_GetFontHeight() + 8, GUI_WHITE, GUI_BLACK);
		}
		
		for (int i = 0; i < txtSize; i++)
		{
			char tmp[2] = { 0, 0, };
			tmp[0] = txtBuf[i];

			dispPosX = (LCD_SIM_WIDTH / 4 + 5 + i * LCD_GetFontWidth() / 2) % (LCD_SIM_WIDTH - 7);
			dispPosY = y + i * LCD_GetFontWidth() / 2 / (LCD_SIM_WIDTH - 7) * LCD_GetFontHeight() + 10;

			if (i == txtPos)
			{
				GUI_DispStringAtLock(tmp, dispPosX, dispPosY + LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);
			} else
			{
				GUI_DispStringAtLock(tmp, dispPosX, dispPosY + LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
			}
		}
		
		for (int i = 0; i < charTableSize; i++)
		{
			if (txtBuf[txtPos] == charTable[i])
			{
				curPosInCharTable = i;
				break;
			}
		}

		LcdRefresh();
				
		while (1)
		{
			Sleep(100);
			mkey = GetKey();
			if (mkey.key != 0)
			{
				break;
			}
		
			if (mkey.idle > retTime / 1000 || mkey.key == KEY_ESC)
			{
				return -1;
			}
			
			DWORD dwTick = GetTick();
			if (g_dwStateTaskClick==0 || dwTick>(g_dwStateTaskClick+500))
			{
				//StateTask();
				g_fLcdRefresh = true;
				g_dwStateTaskClick = dwTick;
			}
			
			if (g_fLcdRefresh)
			{			
				g_fLcdRefresh = false;
				LcdRefresh();			
			}
		}

		if (mkey.key == KEY_ESC)
		{
			return -1;
		}
		if (mkey.key == KEY_OK)
		{
			if (txtSize > 2)
			{
				memcpy(text, txtBuf, txtSize - 2);
			}
			return txtPos;
		}
		if (mkey.key == KEY_UP)
		{
			curPosInCharTable++;
			if (curPosInCharTable >= charTableSize)
			{
				curPosInCharTable = 0;
			}
			txtBuf[txtPos] = charTable[curPosInCharTable];
		}
		if (mkey.key == KEY_DOWN)
		{
			curPosInCharTable--;
			if (curPosInCharTable < 0)
			{
				curPosInCharTable = charTableSize - 1;
			}
			txtBuf[txtPos] = charTable[curPosInCharTable];
		}
		if (mkey.key == KEY_LEFT)
		{
			if (txtPos > 0)
			{
				txtPos--;
			}
		}
		if (mkey.key == KEY_RIGHT)
		{
			if (txtPos < txtSize - 3)
			{
				txtPos++;
			}
		}
	
		for (int i = 0; i < charTableSize; i++)
		{
			if (txtBuf[txtPos] == charTable[i])
			{
				curPosInCharTable = i;
				break;
			}
		}
	}

	return -1;
}
//140228 wulh add end

int MsgBoxSaveParam(int retTime, int msgType, char *title)
{
    struct AppKeyStruct mkey;

    clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());

    while (1)
    {
        switch (msgType)
        {
        case 0:
        {
            /*
               //����һ������
               GUI_DrawRectLock(3,36,158,98);

               //�ػ���һ������
               GUI_DrawRectLock(4,37,157,97);

               //���ڶ�������
               GUI_DrawRectLock(9,42,152,92);

               //����һ��Բ
               GUI_DrawCircle(30,65,17);

               //���ڶ���Բ
               GUI_DrawCircle(30,65,12);

               //��"?"�ַ�
               GUI_DispStringAtLock("?",27, 58, GUI_WHITE, GUI_BLACK);
             */

            //��"��ʾ"�ַ�
            GUI_DispStringAtLock("��  ʾ", 90, 44, GUI_WHITE, GUI_BLACK);

            //��"�Ƿ񱣴��޸�"�ַ�
            GUI_DispStringAtLock("�Ƿ񱣴��޸�", 60, 60, GUI_WHITE, GUI_BLACK);

            //��"ȷ��:�� ȡ��:��"�ַ�
            GUI_DispStringAtLock("ȷ��:�� ȡ��:��", 46, 76, GUI_WHITE, GUI_BLACK);

        }
        break;
        case 1:
        {
            char msgTitle[512];
            if (NULL != title && strlen(title) > 0)
            {
                sprintf(msgTitle, "ȷ���޸�%s?", title);
            }
            else
            {
                strcpy(msgTitle, "ȷ���޸Ĳ���");
            }

            GUI_DispStringHCenterAtLock(msgTitle, LCD_GET_XSIZE() / 2, 3 * LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);

            strcpy(msgTitle, "ȡ��   ȷ��");

            GUI_DispStringHCenterAtLock(msgTitle, LCD_GET_XSIZE() / 2 - 3, 5 * LCD_GetFontHeight() + 10, GUI_WHITE, GUI_BLACK);

        }
        break;
        }

        LcdRefresh();

        while (1)
        {
            Sleep(100);
            mkey = GetKey();
            if (mkey.key != 0)
            {
                break;
            }

            if (mkey.idle > retTime / 1000)
            {
                return -1;
            }

            DWORD dwTick = GetTick();
            if (g_dwStateTaskClick == 0 || dwTick > (g_dwStateTaskClick + 500))
            {
                //StateTask();
                g_fLcdRefresh = true;
                g_dwStateTaskClick = dwTick;
            }

            if (g_fLcdRefresh)
            {
                g_fLcdRefresh = false;
                LcdRefresh();
            }
        }

        if (mkey.key == KEY_ESC || mkey.key == KEY_OK)
        {
            return mkey.key;
        }
    }

}


int EditPasswordBox(int y, char title1[], char text[], int retTime, int txtSize, int dataType, bool fMask)
{
    struct AppKeyStruct mkey;
    char txtBuf[96];
    int txtPos = 0;
    int curPosInCharTable = 0;
    int charTableSize = 0;
    char *charTable;
    int haveTitle = 0;
    bool fFirst = false;
    bool fModify = false;

    clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());

    y = y * LCD_GetFontHeight();

    if (strlen(title1) > 0)
    {
        haveTitle = 1;
    }

    memset(txtBuf, ' ', sizeof(txtBuf));
    if (txtSize == 0)
    {
        txtSize = sizeof(txtBuf);
    }
    else
    {
        txtSize += 2;
        if (txtSize > (int)sizeof(txtBuf))
        {
            txtSize = sizeof(txtBuf);
        }
    }

    text[txtSize - 2] = 0;
    int initTextSize = strlen(text);
    if (initTextSize > txtSize - 2)
    {
        initTextSize = txtSize - 2;
    }
    if (initTextSize > 0)
    {
        memcpy(txtBuf, text, initTextSize);
    }
    txtBuf[txtSize - 1] = 0;

    switch (dataType)
    {
    case DATA_HEX:
        charTable = HexCharTable;
        charTableSize = sizeof(HexCharTable);
        break;
    case DATA_DEC:
        charTable = DecCharTable;
        charTableSize = sizeof(DecCharTable);
        break;
    case DATA_BIN:
        charTable = BinCharTable;
        charTableSize = sizeof(BinCharTable);
        break;
    default:
        charTable = AscCharTable;
        charTableSize = sizeof(AscCharTable);
        break;
    }

    int totalLine = txtSize / ((LCD_SIM_WIDTH - 8) / LCD_GetFontWidth()) / 2 + 2;
    int dispPosX = 0;
    int dispPosY = y;


    //��ѡ�й���ƶ����ַ����һ���ַ�
    txtPos = txtSize - 3;

    while (1)
    {
        if (haveTitle == 1)
        {
            GUI_DispStringHCenterAtLock(title1, LCD_SIM_WIDTH / 2, y -  LCD_GetFontHeight() / 4 + 2, GUI_WHITE, GUI_BLACK);
        }

        for (int i = 0; i < txtSize; i++)
        {
            char tmp[2] = { 0, 0, };
            tmp[0] = txtBuf[i];

            dispPosX = (LCD_SIM_WIDTH / 3 + 5 + i * LCD_GetFontWidth() / 2) % (LCD_SIM_WIDTH - 7);
            dispPosY = y + i * LCD_GetFontWidth() / 2 / (LCD_SIM_WIDTH - 7) * LCD_GetFontHeight() + 10;

            if (i == txtPos)
            {
                GUI_DispStringAtLock(tmp, dispPosX, dispPosY + LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);

                if ( fMask && ((!fFirst && i < txtSize - 2) || !fModify))
                {
                    fFirst = true;
                    GUI_DispStringAtLock("*", dispPosX, dispPosY + LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);
                }

            }
            else
            {
                GUI_DispStringAtLock(tmp, dispPosX, dispPosY + LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);

                if (fMask && (i < txtSize - 2))
                {
                    GUI_DispStringAtLock("*", dispPosX, dispPosY + LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
                }
            }


        }


        for (int i = 0; i < charTableSize; i++)
        {
            if (txtBuf[txtPos] == charTable[i])
            {
                curPosInCharTable = i;
                break;
            }
        }

        //LcdRefresh();

        if (fMask && fModify)
        {
            Sleep(1000);

            dispPosX = (LCD_SIM_WIDTH / 3 + 5 + txtPos * LCD_GetFontWidth() / 2) % (LCD_SIM_WIDTH - 7);
            dispPosY = y + txtPos * LCD_GetFontWidth() / 2 / (LCD_SIM_WIDTH - 7) * LCD_GetFontHeight() + 10;

            GUI_DispStringAtLock("*", dispPosX, dispPosY + LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);

            LcdRefresh();

            fModify = false;
        }
		else
		{
			LcdRefresh();
		}

        while (1)
        {
            Sleep(100);
            mkey = GetKey();
            if (mkey.key != 0)
            {
                break;
            }

            if (mkey.idle > retTime / 1000 || mkey.key == KEY_ESC)
            {
                return -1;
            }

            DWORD dwTick = GetTick();
            if (g_dwStateTaskClick == 0 || dwTick > (g_dwStateTaskClick + 500))
            {
                //StateTask();
                g_fLcdRefresh = true;
                g_dwStateTaskClick = dwTick;
            }

            if (g_fLcdRefresh)
            {
                g_fLcdRefresh = false;
                LcdRefresh();
            }
        }

        if (mkey.key == KEY_ESC)
        {
            return -1;
        }
        if (mkey.key == KEY_OK)
        {
            if (txtSize > 2)
            {
                memcpy(text, txtBuf, txtSize - 2);
            }
            return txtPos;
        }
        if (mkey.key == KEY_UP)
        {
            curPosInCharTable++;
            if (curPosInCharTable >= charTableSize)
            {
                curPosInCharTable = 0;
            }
            txtBuf[txtPos] = charTable[curPosInCharTable];
            fModify = true;
        }
        if (mkey.key == KEY_DOWN)
        {
            curPosInCharTable--;
            if (curPosInCharTable < 0)
            {
                curPosInCharTable = charTableSize - 1;
            }
            txtBuf[txtPos] = charTable[curPosInCharTable];
            fModify = true;
        }
        if (mkey.key == KEY_LEFT)
        {
            if (txtPos > 0)
            {
                txtPos--;
            }
        }
        if (mkey.key == KEY_RIGHT)
        {
            if (txtPos < txtSize - 3)
            {
                txtPos++;
            }
        }

        for (int i = 0; i < charTableSize; i++)
        {
            if (txtBuf[txtPos] == charTable[i])
            {
                curPosInCharTable = i;
                break;
            }
        }
    }

    return -1;
}

/////////////////////////////////////////////////////////////////////
CMyListBox::CMyListBox()
{
    curItem = 0;
    startItem = 0;
    totalItem = 0;
    haveTitle = 0;
}
CMyListBox::~CMyListBox()
{

}

int CMyListBox::Run(int x, char title[], struct ListBoxItemStruct menu[], int retKey, int retTime)
{
    struct AppKeyStruct mkey;

    key = -1;
    if (title != NULL && strlen(title) > 0)
    {
        haveTitle = 1;
    }

    mkey.key = 'R';
    mkey.idle = 0;

    WORD TmptotalItem = 0;

    while (menu[TmptotalItem].text != NULL && menu[TmptotalItem].text != 0)
    {
        TmptotalItem++;
    }

    if (TmptotalItem < 1)
    {
        return -1;
    }

    if (TmptotalItem < totalItem)
    {
        startItem = 0;
        curItem = 0;
    }

    totalItem = TmptotalItem;
    clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());

    while (1)
    {

        if (mkey.key != 0)
        {
            int cnt = 0, no = 0;
            while (menu[startItem + cnt].text != 0)
            {
                if (haveTitle > 0)
                {
                    GUI_DispStringHCenterAtLock(title, LCD_GET_XSIZE() / 2, LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
                }

                if (cnt + 2 < LCD_GetmaxLinePerScreen() - haveTitle)
                {
                    char num[8];
                    if (menu[startItem + cnt].haveNo == 0xFF)
                    {
                        sprintf(num, "%d.", startItem + cnt + 1 - no);
                    }
                    else if (menu[startItem + cnt].haveNo == 0xFE)
                    {
                        sprintf(num, " ");
                        no++;
                    }
                    else
                    {
                        sprintf(num, "%d.", menu[startItem + cnt].haveNo);
                        no++;
                    }

                    if ((startItem + cnt) == curItem)
                    {
                        GUI_DispStringAtLock("                       ", 0, (cnt + 1 + haveTitle) 
                                                    * LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);

                        GUI_DispStringAtLock(num, x + LCD_GetFontWidth() / 2, (cnt + 1 + haveTitle)
                                                       * LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);
                        if (menu[startItem + cnt].haveNo == 0xFE)
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + LCD_GetFontWidth(),
                                (cnt + 1 + haveTitle) * LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);
                        }
                        else
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + 2 * LCD_GetFontWidth(), 
                                (cnt + 1 + haveTitle) * LCD_GetFontHeight(), GUI_BLACK, GUI_WHITE);
                        }
                    }
                    else
                    {

                        GUI_DispStringAtLock("                       ", 0, (cnt + 1 + haveTitle) * LCD_GetFontHeight(),
                                             GUI_WHITE, GUI_BLACK);

                        GUI_DispStringAtLock(num, x + LCD_GetFontWidth() / 2, (cnt + 1 + haveTitle)
                                             * LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
                        if (menu[startItem + cnt].haveNo == 0xFE)
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + LCD_GetFontWidth(), (cnt + 1
                                                                                                      + haveTitle) * LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
                        }
                        else
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + 2 * LCD_GetFontWidth(), (cnt + 1
                                                                                                          + haveTitle) * LCD_GetFontHeight(), GUI_WHITE, GUI_BLACK);
                        }
                    }
                }
                cnt++;
            }
            g_fLcdRefresh = true;
        }

        DWORD dwTick = GetTick();
        if (g_dwStateTaskClick == 0 || dwTick > (g_dwStateTaskClick + 500))
        {
            //StateTask();
            g_fLcdRefresh = true;
            g_dwStateTaskClick = dwTick;
        }

        if (g_fLcdRefresh)
        {
            g_fLcdRefresh = false;
            LcdRefresh();
        }

        //while (1)
        {
            //Sleep(50);
            mkey = GetKey();
            //if (mkey.key != 0)
            //{
            //	break;
            //}

            if (mkey.idle > retTime / 1000)
            {
                //BlightOn(false);
                g_fLcdRefresh = true;
                key = KEY_NULL;
                //clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());
                return MENU_TIMEOUT;
            }
        }

        Sleep(100);

        if (mkey.key == 0)
        {
            continue;
        }

        item = curItem;
        if (mkey.key == (retKey & 0xFF) || mkey.key == ((retKey >> 8) & 0xFF) || mkey.key == ((retKey >> 16) & 0xFF)
            || mkey.key == ((retKey >> 24) & 0xFF) || mkey.key == KEY_ESC)
        {
            key = mkey.key;
            g_fLcdRefresh = true;
            break;
        }
        if (mkey.key == KEY_OK)
        {
            key = KEY_OK;
            if (menu[curItem].fun != NULL)
            {
                if (menu[curItem].fun(menu[curItem].arg) >= 0) //由调用控制是否退�?
                {
                    g_fLcdRefresh = true;
                    break;
                }
            }
            else
            {
                g_fLcdRefresh = true;
                break;
            }
            clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());
        }
        else if (mkey.key == KEY_DOWN)
        {
            curItem++;
            if (curItem >= totalItem)
            {
                curItem = 0;
            }
        }
        else if (mkey.key == KEY_UP)
        {
            curItem--;
            if (curItem < 0)
            {
                curItem = totalItem - 1;
            }
        }

        while (startItem + LCD_GetmaxLinePerScreen() - haveTitle <= curItem + 2)
        {
            startItem++;
            if (startItem > totalItem)
            {
                startItem = totalItem;
            }
        }
        while (startItem > curItem)
        {
            startItem--;
        }
    }

    clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());
    return 0;
}
int CMyListBox::Run(int x, int y, int titleGap, int textGap, bool fFocus, char title[], struct ListBoxItemStruct menu[], int retKey, int retTime)
{
    struct AppKeyStruct mkey;

    key = -1;
    if (title != NULL && strlen(title) > 0)
    {
        haveTitle = 1;
    }

    mkey.key = 'R';
    mkey.idle = 0;

    WORD TmptotalItem = 0;
    short haveGap = 0;

    while (menu[TmptotalItem].text != NULL && menu[TmptotalItem].text != 0)
    {
        TmptotalItem++;
    }

    if (TmptotalItem < 1)
    {
        return -1;
    }

    if (TmptotalItem < totalItem)
    {
        startItem = 0;
        curItem = 0;
    }

    totalItem = TmptotalItem;
    clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());

    haveGap = (titleGap + (totalItem - 1) * textGap + y) / LCD_GetFontHeight() + ((titleGap + (totalItem - 1) * textGap + y) % LCD_GetFontHeight() == 0 ? 0 : 1);

    while (1)
    {
        if (mkey.key != 0)
        {
            int cnt = 0, no = 0;
            while (menu[startItem + cnt].text != 0)
            {
                if (haveTitle > 0)
                {
                    GUI_DispStringHCenterAtLock(title, LCD_GET_XSIZE() / 2, LCD_GetFontHeight() + y, GUI_WHITE, GUI_BLACK);
                }

                if (cnt + 2 < LCD_GetmaxLinePerScreen() - haveTitle - haveGap)
                {
                    char num[8];
                    if (menu[startItem + cnt].haveNo == 0xFF)
                    {
                        sprintf(num, "%d.", startItem + cnt + 1 - no);
                    }
                    else if (menu[startItem + cnt].haveNo == 0xFE)
                    {
                        sprintf(num, " ");
                        no++;
                    }
                    else
                    {
                        sprintf(num, "%d.", menu[startItem + cnt].haveNo);
                        no++;
                    }

                    if ((startItem + cnt) == curItem && fFocus)
                    {
                        GUI_DispStringAtLock("                       ", 0, (cnt + 1 + haveTitle ) * LCD_GetFontHeight() + titleGap + (cnt * textGap) + y,
                                             GUI_BLACK, GUI_WHITE);

                        GUI_DispStringAtLock(num, x + LCD_GetFontWidth() / 2, (cnt + 1 + haveTitle)
                                             * LCD_GetFontHeight() + titleGap + (cnt * textGap) + y, GUI_BLACK, GUI_WHITE);
                        if (menu[startItem + cnt].haveNo == 0xFE)
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + LCD_GetFontWidth(), (cnt + 1
                                                                                                      + haveTitle) * LCD_GetFontHeight() + titleGap + (cnt * textGap) + y, GUI_BLACK, GUI_WHITE);
                        }
                        else
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + 2 * LCD_GetFontWidth(), (cnt + 1
                                                                                                          + haveTitle) * LCD_GetFontHeight() + titleGap + (cnt * textGap) + y, GUI_BLACK, GUI_WHITE);
                        }
                    }
                    else
                    {

                        GUI_DispStringAtLock("                       ", 0, (cnt + 1 + haveTitle) * LCD_GetFontHeight() + titleGap  + (cnt * textGap) + y,
                                             GUI_WHITE, GUI_BLACK);

                        GUI_DispStringAtLock(num, x + LCD_GetFontWidth() / 2, (cnt + 1 + haveTitle)
                                             * LCD_GetFontHeight() + titleGap + (cnt * textGap) + y, GUI_WHITE, GUI_BLACK);
                        if (menu[startItem + cnt].haveNo == 0xFE)
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + LCD_GetFontWidth(), (cnt + 1
                                                                                                      + haveTitle) * LCD_GetFontHeight() + titleGap + (cnt * textGap) + y, GUI_WHITE, GUI_BLACK);
                        }
                        else
                        {
                            GUI_DispStringAtLock(menu[startItem + cnt].text, x + 2 * LCD_GetFontWidth(), (cnt + 1
                                                                                                          + haveTitle) * LCD_GetFontHeight() + titleGap + (cnt * textGap) + y, GUI_WHITE, GUI_BLACK);
                        }
                    }
                }
                cnt++;
            }


            g_fLcdRefresh = true;
        }

        DWORD dwTick = GetTick();
        if (g_dwStateTaskClick == 0 || dwTick > (g_dwStateTaskClick + 500))
        {
            //StateTask();
            g_fLcdRefresh = true;
            g_dwStateTaskClick = dwTick;
        }

        if (g_fLcdRefresh)
        {
            g_fLcdRefresh = false;
            LcdRefresh();
        }

        //while (1)
        {
            //Sleep(50);
            mkey = GetKey();
            //if (mkey.key != 0)
            //{
            //	break;
            //}

            if (mkey.idle > retTime / 1000)
            {
                //BlightOn(false);
                g_fLcdRefresh = true;
                key = KEY_NULL;
                //clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());
                return MENU_TIMEOUT;
            }
        }

        Sleep(100);

        if (mkey.key == 0)
        {
            continue;
        }

        item = curItem;
        if (mkey.key == (retKey & 0xFF) || mkey.key == ((retKey >> 8) & 0xFF) || mkey.key == ((retKey >> 16) & 0xFF)
            || mkey.key == ((retKey >> 24) & 0xFF) || mkey.key == KEY_ESC)
        {
            key = mkey.key;
            g_fLcdRefresh = true;
            break;
        }
        if (mkey.key == KEY_OK)
        {
            key = KEY_OK;
            if (menu[curItem].fun != NULL)
            {
                if (menu[curItem].fun(menu[curItem].arg) >= 0) //由调用控制是否退�?
                {
                    g_fLcdRefresh = true;
                    break;
                }
            }
            else
            {
                g_fLcdRefresh = true;
                break;
            }
            clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());
        }
        else if (mkey.key == KEY_DOWN)
        {
            curItem++;
            if (curItem >= totalItem)
            {
                curItem = 0;
            }
        }
        else if (mkey.key == KEY_UP)
        {
            curItem--;
            if (curItem < 0)
            {
                curItem = totalItem - 1;
            }
        }

        while (startItem + LCD_GetmaxLinePerScreen() - haveTitle - haveGap <= curItem + 2)
        {
            startItem++;
            if (startItem > totalItem)
            {
                startItem = totalItem;
            }
        }
        while (startItem > curItem)
        {
            startItem--;
        }
    }

    clear_screen_rec(0, LCD_GetFontHeight(), LCD_SIM_WIDTH, LCD_SIM_HEIGHT - LCD_GetFontHeight());
    return 0;
}
